﻿namespace Phone.Framework.Controls
{
    using System;
    using System.Runtime.CompilerServices;
    using System.Windows;
    using System.Windows.Controls;

    public class UniformGrid : Panel
    {
        public static readonly DependencyProperty ColumnsProperty = DependencyProperty.Register("Columns", typeof(int), typeof(UniformGrid), new PropertyMetadata(0, new PropertyChangedCallback(UniformGrid.OnIntegerDependencyPropertyChanged)));
        public static readonly DependencyProperty FirstColumnProperty = DependencyProperty.Register("FirstColumn", typeof(int), typeof(UniformGrid), new PropertyMetadata(0, new PropertyChangedCallback(UniformGrid.OnIntegerDependencyPropertyChanged)));
        public static readonly DependencyProperty RowsProperty = DependencyProperty.Register("Rows", typeof(int), typeof(UniformGrid), new PropertyMetadata(0, new PropertyChangedCallback(UniformGrid.OnIntegerDependencyPropertyChanged)));

        protected override Size ArrangeOverride(Size arrangeSize)
        {
            Rect finalRect = new Rect(0.0, 0.0, arrangeSize.Width / ((double) this.ComputedColumns), arrangeSize.Height / ((double) this.ComputedRows));
            double width = finalRect.Width;
            double num2 = arrangeSize.Width - 1.0;
            finalRect.X += finalRect.Width * this.FirstColumn;
            foreach (UIElement element in base.Children)
            {
                element.Arrange(finalRect);
                if (element.Visibility != Visibility.Collapsed)
                {
                    finalRect.X += width;
                    if (finalRect.X >= num2)
                    {
                        finalRect.Y += finalRect.Height;
                        finalRect.X = 0.0;
                    }
                }
            }
            return arrangeSize;
        }

        protected override Size MeasureOverride(Size constraint)
        {
            this.UpdateComputedValues();
            Size availableSize = new Size(constraint.Width / ((double) this.ComputedColumns), constraint.Height / ((double) this.ComputedRows));
            double width = 0.0;
            double height = 0.0;
            int num3 = 0;
            int count = base.Children.Count;
            while (num3 < count)
            {
                UIElement element = base.Children[num3];
                element.Measure(availableSize);
                Size desiredSize = element.DesiredSize;
                if (width < desiredSize.Width)
                {
                    width = desiredSize.Width;
                }
                if (height < desiredSize.Height)
                {
                    height = desiredSize.Height;
                }
                num3++;
            }
            return new Size(width * this.ComputedColumns, height * this.ComputedRows);
        }

        private static void OnIntegerDependencyPropertyChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
        {
            if (!(e.NewValue is int) || (((int) e.NewValue) < 0))
            {
                o.SetValue(e.Property, e.OldValue);
            }
        }

        private void UpdateComputedValues()
        {
            this.ComputedColumns = this.Columns;
            this.ComputedRows = this.Rows;
            if (this.FirstColumn >= this.ComputedColumns)
            {
                this.FirstColumn = 0;
            }
            if ((this.ComputedRows == 0) || (this.ComputedColumns == 0))
            {
                int num = 0;
                int num2 = 0;
                int count = base.Children.Count;
                while (num2 < count)
                {
                    UIElement element = base.Children[num2];
                    if (element.Visibility != Visibility.Collapsed)
                    {
                        num++;
                    }
                    num2++;
                }
                if (num == 0)
                {
                    num = 1;
                }
                if (this.ComputedRows == 0)
                {
                    if (this.ComputedColumns > 0)
                    {
                        this.ComputedRows = ((num + this.FirstColumn) + (this.ComputedColumns - 1)) / this.ComputedColumns;
                    }
                    else
                    {
                        this.ComputedRows = (int) Math.Sqrt((double) num);
                        if ((this.ComputedRows * this.ComputedRows) < num)
                        {
                            this.ComputedRows++;
                        }
                        this.ComputedColumns = this.ComputedRows;
                    }
                }
                else if (this.ComputedColumns == 0)
                {
                    this.ComputedColumns = (num + (this.ComputedRows - 1)) / this.ComputedRows;
                }
            }
        }

        public int Columns
        {
            get
            {
                return (int) base.GetValue(ColumnsProperty);
            }
            set
            {
                base.SetValue(ColumnsProperty, value);
            }
        }

        private int ComputedColumns { get; set; }

        private int ComputedRows { get; set; }

        public int FirstColumn
        {
            get
            {
                return (int) base.GetValue(FirstColumnProperty);
            }
            set
            {
                base.SetValue(FirstColumnProperty, value);
            }
        }

        public int Rows
        {
            get
            {
                return (int) base.GetValue(RowsProperty);
            }
            set
            {
                base.SetValue(RowsProperty, value);
            }
        }
    }
}

